/******************************************************************************
                         COPYRIGHT 1955-2008 by BUPT ISC.
                        北京邮电大学信息安全中心 版权所有
                           Web: http://www.bupt.edu.cn
 *******************************************************************************/
/*******************************************************************************
  文件名： log_pthread.c
  项目：   
  模块：   log
  作者：   huangwei
  版本：   0.1
  创建于:  2009-03-20
  描述：
    线程安全日志操作函数集

  修改历史： 
  日期：     修改人：     修改描述：
  
 *********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <pthread.h>
#include <sys/mman.h>

#include "memory.h"
#include "log_pthread.h"
#include "log.h"

void logSafe (int prio, char * fmt, va_list ap)
{
    pthread_mutex_lock(logq_lock);
    enLogQueue(prio, fmt, ap);
    va_end(ap);
    pthread_mutex_unlock(logq_lock);

    pthread_mutex_lock(logev_lock);
    pthread_cond_signal(logev_cond);
    pthread_mutex_unlock(logev_lock);
}

static void flushLogQueue (void)
{
    int empty;

    do {
        pthread_mutex_lock(logq_lock);
        empty = deLogQueue(g_pstLogArea->pcBuff);
        pthread_mutex_unlock(logq_lock);
#if 0
        logSyslog(g_pstLogArea->pcBuff);
#endif
    } while (empty == 0);
}

static void * log_thread (void * et)
{
    mlockall(MCL_CURRENT | MCL_FUTURE);
    logdbg(stderr,"enter log_thread\n");

    while (1) {
        pthread_mutex_lock(logev_lock);
        pthread_cond_wait(logev_cond, logev_lock);
        pthread_mutex_unlock(logev_lock);

        flushLogQueue();
    }

    return NULL;
}

/******************************************************************************
  函数名：startLogThread
  功能描述：
    启动日志线程，初始化日志缓冲区

  输入参数：
    无

  输出参数：
    无

  返回值：
    无
 *****************************************************************************/
void startLogThread (void)
{
    pthread_attr_t attr;

    logdbg(stderr,"enter startLogThread\n");

    logq_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
    logev_lock = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
    logev_cond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));

    pthread_mutex_init(logq_lock, NULL);
    pthread_mutex_init(logev_lock, NULL);
    pthread_cond_init(logev_cond, NULL);

    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, DEFAULT_AREA_SIZE);

    pthread_create(&log_thr, &attr, log_thread, NULL);

    return;
}

/******************************************************************************
  函数名：startLogThread
  功能描述：
    停止日志线程，清理日志缓冲区

  输入参数：
    无

  输出参数：
    无

  返回值：
    无
 *****************************************************************************/
void stopLogThread (void)
{
    if (log_thr == 0 || logev_lock == NULL || 
            logq_lock == NULL || logev_cond == NULL) /* 避免重复调用stopLogThread函数 */
    {
        return;
    }
    logdbg(stderr,"enter stopLogThread\n");

    pthread_mutex_lock(logq_lock);
    pthread_cancel(log_thr);
    pthread_mutex_unlock(logq_lock);

    /* 将日志缓冲区中的日志写入指定位置 */
    flushLogQueue();

    pthread_mutex_destroy(logq_lock);
    pthread_mutex_destroy(logev_lock);
    pthread_cond_destroy(logev_cond);

    /* 清空日志缓冲区 */
    freeLogarea();
}

